package zjut.raymond.witdemo.ui;

import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PointF;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.blakequ.bluetooth_manager_lib.BleManager;
import com.blakequ.bluetooth_manager_lib.BleParamsOptions;
import com.blakequ.bluetooth_manager_lib.BuildConfig;
import com.blakequ.bluetooth_manager_lib.connect.BluetoothConnectManager;
import com.blakequ.bluetooth_manager_lib.connect.BluetoothSubScribeData;
import com.blakequ.bluetooth_manager_lib.connect.ConnectConfig;
import com.blakequ.bluetooth_manager_lib.connect.ConnectState;
import com.blakequ.bluetooth_manager_lib.connect.ConnectStateListener;
import com.davemorrissey.labs.subscaleview.ImageSource;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.StringJoiner;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

import cn.finalteam.okhttpfinal.HttpRequest;
import cn.finalteam.okhttpfinal.RequestParams;
import zjut.raymond.witdemo.R;
import zjut.raymond.witdemo.algorithm.Router;
import zjut.raymond.witdemo.algorithm.StepCallback;
import zjut.raymond.witdemo.algorithm.UnscentKalmanFilter;
import zjut.raymond.witdemo.algorithm.Vector3Event;
import zjut.raymond.witdemo.sensor.MyEvent;
import zjut.raymond.witdemo.sensor.SensorData;
import zjut.raymond.witdemo.sensor.SensorDataListener;
import zjut.raymond.witdemo.sensor.SensorType;
import zjut.raymond.witdemo.ui.view.MapView;
import zjut.raymond.witdemo.util.CommonUtils;
import zjut.raymond.witdemo.util.LocationWifiScanUtils;
import zjut.raymond.witdemo.util.MyFile;
import zjut.raymond.witdemo.viewmodel.MyViewModel;

/**
 * A simple {@link Fragment} subclass.
 * create an instance of this fragment.
 */
public class DataFragment extends Fragment implements View.OnClickListener {
    public static final String TAG = "DataFragment";
    private final double GLOBAL_GRAVITY = 9.8;

    public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private MyViewModel viewModel;
    private EditText editTextX, editTextY, editTextFilepath;
    private TextView textView;
    private Button btnInit, btnRecord, btnClearCount;
    private MapView mapView;
    private SensorData sensorData;
    private SensorDataListener sensorDataListener;

    public static Router mRouter = new Router();
    public Vector3Event acc = new Vector3Event();
    public Vector3Event mag = new Vector3Event();
    public Vector3Event gyr = new Vector3Event();

    private BluetoothConnectManager connectManager;  //单设备连接管理器
    private BluetoothAdapter bluetoothAdapter;  //蓝牙适配器
    private BluetoothGatt bluetoothGatt;
    private LocationWifiScanUtils wifiScanUtils;

    private ScheduledExecutorService executorService;
    private UnscentKalmanFilter unscentKalmanFilter;

    private Handler handler;

    //    相关指令
    byte[] cmdSave = new byte[]{(byte) 0xff, (byte) 0xaa, (byte) 0x00, (byte) 0x00, (byte) 0x00};//保存校准
    byte[] cmdQuitCali = new byte[]{(byte) 0xff, (byte) 0xaa, (byte) 0x01, (byte) 0x00, (byte) 0x00};//退出校准
    byte[] cmdAccCali = new byte[]{(byte) 0xff, (byte) 0xaa, (byte) 0x01, (byte) 0x01, (byte) 0x00};//加计校准
    byte[] cmdMagCali = new byte[]{(byte) 0xff, (byte) 0xaa, (byte) 0x01, (byte) 0x07, (byte) 0x00};//磁场校准
    byte[] cmdReqMag = new byte[]{(byte) 0xff, (byte) 0xaa, (byte) 0x27, (byte) 0x3a, (byte) 0x00};//读取磁场
    byte[] cmdReqQuan = new byte[]{(byte) 0xff, (byte) 0xaa, (byte) 0x27, (byte) 0x51, (byte) 0x00};//读取四元数
    byte[] cmdReqTep = new byte[]{(byte) 0xff, (byte) 0xaa, (byte) 0x27, (byte) 0x40, (byte) 0x00};//读取温度
    byte[] cmdSetRate = new byte[]{(byte) 0xff, (byte) 0xaa, (byte) 0x03, (byte) 0x08, (byte) 0x00};//设置回传速率 FF AA 03 RATE 00; RATE: 0x06：10Hz（默认） 0x07：20Hz 0x08：50Hz
    boolean isIdle = true;


    //  PedestrianDeadReckoningAlgorithm algorithm = new PedestrianDeadReckoningAlgorithm();

    public DataFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        setHasOptionsMenu(true);
        return inflater.inflate(R.layout.fragment_data, container, false);
    }


    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        viewModel = new ViewModelProvider(getActivity()).get(MyViewModel.class);
        executorService = Executors.newScheduledThreadPool(10);
        initHandler();
        initCallback();
        initView();
        initObserve();
        //获取需要的权限
        initConfig();  // 蓝牙初始设置
        connectDevice();
    }

    private void initHandler() {
        handler = new Handler(Looper.myLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                Bundle data = msg.getData();
                switch (msg.what) {
                    case 0x01: {
                        double stepLength = data.getDouble("stepLength");
                        double orientation = data.getDouble("orientation");
                        viewModel.addStepCount();
                        if (viewModel.getIsPDRInit().getValue() && viewModel.getPdrLocationResult().getValue() != null) {
                            unscentKalmanFilter.onStepUpdate(stepLength, orientation);
                            PointF p = viewModel.getPdrLocationResult().getValue();
                            double dx = stepLength * 36 * Math.sin(Math.toRadians(orientation));
                            double dy = stepLength * 36 * Math.cos(Math.toRadians(orientation));
                            p.x += dx;
                            p.y -= dy;
//                    PointF tmp = barrierProcess(p);
//                            myViewModel.setPdrLocationResult(p);
//                            mRouter.set(p);
                            //                           viewModel.setPdrLocationResult(p);

//                    PointF p1 = myViewModel.getFusionLocationResult().getValue();
//                    p1.x += dx;
//                    p1.y -= dy;
//                    myViewModel.setFusionLocationResult(barrierProcess(p1));
//                    mFusionRouter.set(barrierProcess(p1));
                        }
                    }
                    break;
                    case 0x02: {
                        double orientation = data.getDouble("orientation");
                        mapView.updateOrientation((float) orientation);
                    }
                    break;
                    default:
                        super.handleMessage(msg);
                        break;
                }
            }
        };
    }

    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.nav_menu, menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.item_cali_acc:
                if (writeCalBytes(cmdAccCali)) {
                    Toast.makeText(getActivity(), "加速度计校准中，请保持设备水平静止5s!", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getActivity(), "加速度计校准失败，请重新校准!", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.item_cali_mag:
                if (writeCalBytes(cmdMagCali)) {
                    Toast.makeText(getActivity(), "磁力计校准开始！", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.item_complate_cali_mag:

                if (writeCalBytes(cmdQuitCali)) {
                    Toast.makeText(getActivity(), "磁场校准完成", Toast.LENGTH_SHORT).show();

                    //     writeCalBytes(cmdSave);
                }

                break;
            case R.id.item_save:
                if (writeBytes(cmdSave)) {
                    Toast.makeText(getActivity(), "配置保存成功", Toast.LENGTH_SHORT).show();
                } else Toast.makeText(getActivity(), "配置保存失败", Toast.LENGTH_SHORT).show();

                break;
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    private void initCallback() {
        sensorData = new SensorData();
        sensorDataListener = new SensorDataListener();
        sensorDataListener.setStepCallback(new StepCallback() {
            @Override
            public void onLocationChanged(double stepLength, double orientation) {
                Log.d(TAG, "onLocationChanged: 动态步长：" + stepLength + " " + orientation);
                Message message = new Message();
                message.what = 0x01;
                Bundle bundle = new Bundle();
                bundle.putDouble("stepLength", stepLength);
                bundle.putDouble("orientation", orientation);
                message.setData(bundle);
                handler.sendMessage(message);
            }

            @Override
            public void onOrientationChanged(double orientation) {
                Message message = new Message();
                message.what = 0x02;
                Bundle bundle = new Bundle();
                bundle.putDouble("orientation", orientation);
                message.setData(bundle);
                handler.sendMessage(message);
            }
        });
        sensorData.registerObserver(sensorDataListener);

        wifiScanUtils = new LocationWifiScanUtils(getContext());
        wifiScanUtils.setChangedCallback((x, y) -> {
            PointF f = new PointF((float) x, (float) y);
            mapView.updateWifiLocation(f);
            if (!viewModel.getIsPDRInit().getValue()) {
                //   viewModel.setPdrLocationResult(f);
                viewModel.setIsPDRInit(true);
            } else {
                if (unscentKalmanFilter != null) {
                    unscentKalmanFilter.onWifiLocationChange(f);
                }
            }
        });
    }

    private void initObserve() {
        viewModel.getDeviceMac().observe(getActivity(), s -> Log.d(TAG, "onChanged: " + s));
        viewModel.getPdrLocationResult().observe(getActivity(), pointF -> {
            Log.d(TAG, "onChanged: location" + pointF.toString());
            mRouter.set(pointF);
            mapView.updatePDRLocation(pointF);

            executorService.execute(() -> {
                RequestParams params = new RequestParams();
                JSONObject jo = new JSONObject();
                jo.put("x", (int) pointF.x);
                jo.put("y", (int) pointF.y);
                params.addFormDataPart("location", JSON.toJSONString(jo));

                HttpRequest.post("http://47.101.186.100:9102/location/pdrLocation", params);
            });
        });
        viewModel.getBooleanRecord().observe(getActivity(), aBoolean -> {
            if (aBoolean) {
                btnRecord.setText(getString(R.string.txt_stop_record));
            } else {
                btnRecord.setText(getString(R.string.txt_start_record));
            }
        });
        viewModel.getStepCount().observe(getActivity(), integer -> textView.setText("步数：" + integer));
    }

    private void initView() {
        mapView = getView().findViewById(R.id.mapView);
        mapView.setImage(ImageSource.bitmap(getImageFromAssetsFile(getContext(), "img/5f.jpg")));
        mapView.setDoubleTapZoomDuration(300);
        editTextX = getView().findViewById(R.id.editTextX);
        editTextY = getView().findViewById(R.id.editTextY);
        textView = getView().findViewById(R.id.tv_acc_value);
        btnInit = getView().findViewById(R.id.btn_init);
        btnInit.setOnClickListener(this);
        btnRecord = getView().findViewById(R.id.btn_switch);
        btnRecord.setOnClickListener(this);
        btnClearCount = getView().findViewById(R.id.btn_clear_count);
        btnClearCount.setOnClickListener(this);
    }

    /* 读取Assets文件夹中的图片资源
     * @param context
     * @param fileName 图片名称
     * @return
     */
    public static Bitmap getImageFromAssetsFile(Context context, String fileName) {
        Bitmap image = null;
        AssetManager am = context.getResources().getAssets();
        try {
            InputStream is = am.open(fileName);
            image = BitmapFactory.decodeStream(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;
    }

    //蓝牙初始化操作
    private void initConfig() {
        connectManager = BleManager.getConnectManager(getContext());
        //获取蓝牙适配器
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            Toast.makeText(getContext(), "蓝牙不可用", Toast.LENGTH_SHORT).show();
            return;
        }
        //蓝牙没打开是打开蓝牙
        if (!bluetoothAdapter.isEnabled()) {
            bluetoothAdapter.enable();
        }
        BleManager.setBleParamsOptions(new BleParamsOptions.Builder()
                .setBackgroundBetweenScanPeriod(5 * 60 * 1000)
                .setBackgroundScanPeriod(10000)
                .setForegroundBetweenScanPeriod(2000)
                .setForegroundScanPeriod(10000)
                .setDebugMode(BuildConfig.DEBUG)
                .setMaxConnectDeviceNum(7)
                .setReconnectBaseSpaceTime(1000)
                .setReconnectMaxTimes(Integer.MAX_VALUE)
                .setReconnectStrategy(ConnectConfig.RECONNECT_LINE_EXPONENT)
                .setReconnectedLineToExponentTimes(5)
                .setConnectTimeOutTimes(20000)
                .build());
    }

    private void connectDevice() {
        String mac = viewModel.getDeviceMac().getValue();
        Log.d(TAG, "----------------: 需要连接的mac" + mac);
        //获取设备的gatt对象
        bluetoothGatt = bluetoothAdapter.getRemoteDevice(mac).connectGatt(getContext(), false, new BluetoothGattCallback() {
        });
        Log.d(TAG, "----------------: 添加了" + mac);
        //如果不用需要移除状态监听removeConnectStateListener
        connectManager.addConnectStateListener(new ConnectStateListener() {
            @Override
            public void onConnectStateChanged(String address, ConnectState state) {
                switch (state) {
                    case CONNECTING:
                        Log.d(TAG, "设备:" + address + "连接状态:" + "正在连接");
                        break;
                    case CONNECTED:
                        Log.d(TAG, "设备:" + address + "连接状态:" + "连接成功");
                        break;
                    case NORMAL:
                        Log.d(TAG, "设备:" + address + "连接状态:" + "连接失败");
                        break;
                }
            }
        });
        //数据回调
        connectManager.setBluetoothGattCallback(new BluetoothGattCallback() {
            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                super.onCharacteristicChanged(gatt, characteristic);
                //解析回调数据
                dealCallDatas(gatt, characteristic);
            }

            @Override
            public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
                super.onDescriptorWrite(gatt, descriptor, status);
            }
            //注意：里面的回调方法都是在非主线程
        });
        //start subscribe auto
//1.set service uuid(将要读取GattService的UUID)
        connectManager.setServiceUUID("0000ffe5-0000-1000-8000-00805f9a34fb");
//2.clean history descriptor data（清除历史订阅读写通知）
        connectManager.cleanSubscribeData();
//3.add subscribe params（读写和通知）
//        connectManager.addBluetoothSubscribeData(
//                new BluetoothSubScribeData.Builder().setCharacteristicRead(UUID.fromString("0000ffe4-0000-1000-8000-00805f9a34fb")).build());//read characteristic
        connectManager.addBluetoothSubscribeData(
                new BluetoothSubScribeData.Builder().setCharacteristicNotify(UUID.fromString("0000ffe4-0000-1000-8000-00805f9a34fb")).build()); //notify
        connectManager.addBluetoothSubscribeData(
                new BluetoothSubScribeData.Builder().setCharacteristicWrite(
                        UUID.fromString("0000ffe9-0000-1000-8000-00805f9a34fb"), cmdSetRate
                ).build());
//        connectManager.addBluetoothSubscribeData(
//                new BluetoothSubScribeData.Builder().setCharacteristicWrite(characteristic.getUuid()).build()); //write characteristic
//        connectManager.addBluetoothSubscribeData(
//                new BluetoothSubScribeData.Builder().setCharacteristicWrite(characteristic.getUuid(), byteData).build();
//还有读写descriptor
//start subscribe(注意，在使用时当回调onServicesDiscovered成功时会自动调用该方法，所以只需要在连接之前完成1,3步即可),如果需要单独读写某些属性，则可以单独调用该方法，并且同样使用步骤2,3然后调用该方法手动启动订阅
        connectManager.connect(mac);
    }

    /**
     * 处理回调的数据
     *
     * @param gatt
     * @param characteristic
     */
    float[] floats = new float[30];

    private void dealCallDatas(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        byte[] value = characteristic.getValue();

        Log.d(TAG, "dealCallDatas: 回调数据" + value[0] + " " + value[1] + " " + value[2] + " " + value[3] + " " + value[4] + " " + value[5] + " " + value[6] + " " + value[7] + " "
                + value[8] + " " + value[9] + " " + value[10] + " " + value[11] + " ");

        if (value[0] != 0x55) {
            return;//开头不是0x55的数据删除
        }
        switch (value[1]) {
            case 0x61: {
                long t = System.currentTimeMillis();
                //加速度数据
                float x = (float) (((((short) value[3]) << 8) | ((short) value[2] & 0xff)) / 32768.0f * 16 * GLOBAL_GRAVITY);   //x轴
                float y = (float) (((((short) value[5]) << 8) | ((short) value[4] & 0xff)) / 32768.0f * 16 * GLOBAL_GRAVITY);   //y轴
                float z = (float) (((((short) value[7]) << 8) | ((short) value[6] & 0xff)) / 32768.0f * 16 * GLOBAL_GRAVITY);   //z轴
                //   executorService.execute(() -> {
                sensorData.setEvent(new MyEvent(x, y, z, System.currentTimeMillis(), SensorType.TYPE_ACCELEROMETER));
                //   });
                //角速度数据
                float gx = ((((short) value[9]) << 8) | ((short) value[8] & 0xff)) / 32768.0f * 2000;  //x轴
                float gy = ((((short) value[11]) << 8) | ((short) value[10] & 0xff)) / 32768.0f * 2000;  //y轴
                float gz = ((((short) value[13]) << 8) | ((short) value[12] & 0xff)) / 32768.0f * 2000;  //z轴
                //   executorService.execute(() -> {
                sensorData.setEvent(new MyEvent(gx, gy, gz, System.currentTimeMillis(), SensorType.TYPE_GYROSCOPE));
                //    });

                StringJoiner stringJoiner = new StringJoiner("\t", "", "\n");
                stringJoiner.add(String.valueOf(acc.x))
                        .add(String.valueOf(acc.y))
                        .add(String.valueOf(acc.z))
                        .add(String.valueOf(gyr.x))
                        .add(String.valueOf(gyr.y))
                        .add(String.valueOf(gyr.z))
                        .add(dateFormat.format(new Date(t)));
                if (viewModel.getBooleanRecord().getValue()) {
                    try {
                        myFile.write(stringJoiner.toString());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                Log.d(TAG, "dealCallDatas:加速度数据 " + acc.toString());
                Log.d(TAG, "dealCallDatas:角速度数据 " + gyr.toString());
                writeBytes(cmdReqMag);
                //==================================================================================


                //================步态检测和步长估计=================================================


            }
            break;
            case 0x71: {
                switch (value[2]) {
                    case 0x3a: {
                        long t = System.currentTimeMillis();
                        //磁场数据
                        float mx = ((((short) value[5]) << 8) | ((short) value[4] & 0xff)) / (float) (4 * Math.PI);   //x轴
                        float my = ((((short) value[7]) << 8) | ((short) value[6] & 0xff)) / (float) (4 * Math.PI);   //y轴
                        float mz = ((((short) value[9]) << 8) | ((short) value[8] & 0xff)) / (float) (4 * Math.PI);   //z轴
                        mag.timestamp = t;
                        //        executorService.execute(() -> {
                        sensorData.setEvent(new MyEvent(mx, my, mz, System.currentTimeMillis(), SensorType.TYPE_MAGNETIC_FIELD));
                        //         });
                        Log.d(TAG, "dealCallDatas: Thread：" + Thread.currentThread().getName());
                        //           algorithm.inputData(acc, mag, gyr);
                        Log.d(TAG, "dealCallDatas: " + mag.toString());
                        //==================================================================================

                    }
                    break;
                    case 0x51:
                        //四元数
                        float q0 = ((((short) value[5]) << 8) | ((short) value[4] & 0xff)) / 32768.0f;
                        float q1 = ((((short) value[7]) << 8) | ((short) value[6] & 0xff)) / 32768.0f;
                        float q2 = ((((short) value[9]) << 8) | ((short) value[8] & 0xff)) / 32768.0f;
                        float q3 = ((((short) value[11]) << 8) | ((short) value[10] & 0xff)) / 32768.0f;
                        Log.d(TAG, "dealCallDatas:四元数数据 " + q0 + " " + q1 + " " + q2 + " " + q3);
                        break;
                    case 0x40:
                        //温度
                        float tep = ((((short) value[5]) << 8) | ((short) value[4] & 0xff)) / 100.0f;
                        Log.d(TAG, "dealCallDatas:温度数据 " + tep);
                        break;
                    default:
                        break;
                }
            }
            break;
            default:
                break;
        }
    }


    String save_path, global_path, step_length_file_path;
    MyFile myFile, step_length_file;

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
//            case R.id.btn_req_mag: {
//                 writeBytes(cmdReqMag);
//                //writeBytes(cmdReqQuan);
//                 //  writeBytes(cmdReqTep);
//            }
//            break;
//            case R.id.btn_cali_acc: {
//                if (writeBytes(cmdAccCali))
//                    Toast.makeText(getContext(), "加计校准中，请保持水平静止5s", Toast.LENGTH_LONG).show();
//            }
//            break;
            case R.id.btn_init: {
                String stringX = editTextX.getText().toString();
                String stringY = editTextY.getText().toString();
                if (CommonUtils.isNumeric(stringX) && CommonUtils.isNumeric(stringY)) {
                    PointF pointF = new PointF(Float.parseFloat(editTextX.getText().toString()), Float.parseFloat(editTextY.getText().toString()));
                    viewModel.setPdrLocationResult(pointF);
                    viewModel.setIsPDRInit(true);
                    mRouter.set(pointF);
                    mapView.updatePDRLocation(pointF);
                    unscentKalmanFilter = new UnscentKalmanFilter(pointF);
                    unscentKalmanFilter.setCallBack(location -> {
                        mRouter.set(location);
                        mapView.updatePDRLocation(location);
                    });
                } else {
                    Toast.makeText(getContext(), "初始坐标输入有误", Toast.LENGTH_LONG).show();
                }
            }
            break;
            case R.id.btn_switch: {
                if (!viewModel.getBooleanRecord().getValue()) {
                    new AlertDialog.Builder(getContext()).setTitle(getString(R.string.input_path))
                            .setView(editTextFilepath = new EditText(getContext()))
                            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                                    Date date = new Date();
                                    String fileTie = simpleDateFormat.format(date);
                                    if (!TextUtils.isEmpty(editTextFilepath.getText().toString())) {
                                        save_path = editTextFilepath.getText().toString();
                                        String feature_file_path = requireContext().getExternalCacheDir() + "/Record/" + save_path;
                                        global_path = feature_file_path + "/record" + fileTie + ".xls";
                                        step_length_file_path = feature_file_path + "/data" + fileTie + ".xls";
                                        Toast.makeText(getContext(), "Save Path: " + feature_file_path, Toast.LENGTH_SHORT).show();
                                        File file = new File(feature_file_path);
                                        if (!file.exists()) {
                                            file.mkdirs();
                                        }
                                        try {
                                            myFile = new MyFile(global_path);
                                            step_length_file = new MyFile(step_length_file_path);
                                            StringJoiner stringJoiner = new StringJoiner("\t", "", "\n");
                                            stringJoiner.add("ax").add("ay").add("az").add("wx").add("wy").add("wz").add("update_time");
                                            myFile.write(stringJoiner.toString());
                                            StringJoiner sj = new StringJoiner("\t", "", "\n");
                                            stringJoiner.add("amax").add("amin").add("steplength").add("std").add("update_time");
                                            step_length_file.write(sj.toString());
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                        viewModel.setBooleanRecord(true);
                                    } else {
                                        Toast.makeText(getContext(), "路径不能为空", Toast.LENGTH_SHORT).show();
                                    }
                                }
                            })
                            .setNegativeButton(R.string.cancel, null)
                            .show();
                } else {
                    if (save_path.length() > 0) {
                        String stopStr = getString(R.string.stop_time) + dateFormat.format(new Date()) + "\r\n";
                        try {
                            myFile.write(stopStr);
                            myFile.close();
                            step_length_file.write(stopStr);
                            step_length_file.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        viewModel.setBooleanRecord(false);
                        new AlertDialog.Builder(getContext())
                                .setTitle(getString(R.string.hint))
                                .setIcon(R.drawable.ic_dialog_alert)
                                .setMessage(getString(R.string.data_record) + global_path)
                                .setPositiveButton("OK", null)
                                .show();
                    }
                }
            }
            break;
            case R.id.btn_clear_count: {
//                if (!TextUtils.isEmpty(editTextX.getText()) && !TextUtils.isEmpty(editTextY.getText())) {
//                    PointF pointF = new PointF(Float.parseFloat(editTextX.getText().toString()), Float.parseFloat(editTextY.getText().toString()));
//                    viewModel.setPdrLocationResult(pointF);
//                    viewModel.setIsPDRInit(true);
//                } else {
//                    Toast.makeText(getContext(), "初始坐标不能为空", Toast.LENGTH_LONG).show();
//                }
                viewModel.clearStepCount();
            }
            break;
            default:
                break;
        }
    }

    private boolean writeCalBytes(byte[] cmd) {
        if (!isIdle) {
            //   Toast.makeText(getContext(), getString(R.string.busywrite), Toast.LENGTH_SHORT).show();
            return false;
        }
        isIdle = false;
        int iDelay = 500;
        if ((cmd[2] == (byte) 0x01) && (cmd[3] == (byte) 0x01)) iDelay = 6000;
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                isIdle = true;
            }
        }, iDelay);
        connectManager.cleanSubscribeData();
        connectManager.addBluetoothSubscribeData(
                new BluetoothSubScribeData.Builder().setCharacteristicWrite(
                        UUID.fromString("0000ffe9-0000-1000-8000-00805f9a34fb"), cmd
                ).build());
        connectManager.startSubscribe(bluetoothGatt);
        //   connectManager.connect(viewModel.getDeviceMac().getValue());
        return true;
    }

    private boolean writeBytes(byte[] cmd) {
        if (!isIdle) {
            //   Toast.makeText(getContext(), getString(R.string.busywrite), Toast.LENGTH_SHORT).show();
            return false;
        }
        connectManager.cleanSubscribeData();
        connectManager.addBluetoothSubscribeData(
                new BluetoothSubScribeData.Builder().setCharacteristicWrite(
                        UUID.fromString("0000ffe9-0000-1000-8000-00805f9a34fb"), cmd
                ).build());
        connectManager.startSubscribe(bluetoothGatt);
        //connectManager.connect(viewModel.getDeviceMac().getValue());
        return true;
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        sensorData.removeObserver(sensorDataListener);
        viewModel.clearStepCount();
        connectManager.disconnect(viewModel.getDeviceMac().getValue());
        wifiScanUtils.destroyed();
        mapView.clearLocationPath();
    }
}